<?php

namespace App\Exceptions;

use App\Models\StatusCode;
use App\Services\CommonReturn;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\QueryException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Throwable;

class Handler extends ExceptionHandler
{
    /**
     * The list of the inputs that are never flashed to the session on validation exceptions.
     *
     * @var array<int, string>
     */
    protected $dontFlash = [
        'current_password',
        'password',
        'password_confirmation',
    ];

    /**
     * Register the exception handling callbacks for the application.
     */
    public function register(): void
    {
        $this->reportable(function (Throwable $e) {
            //
        });
    }


    /**
     * Render an exception into an HTTP response.
     * @author Tinymeng <666@majiameng.com>
     *
     * @param $request
     * @param Throwable $exception
     * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
     * @throws Throwable
     */
    public function render($request, Throwable $exception)
    {
        DB::rollBack();//事务回滚
        //处理404等异常页面
        if ($exception instanceof NotFoundHttpException) {
            $code = $exception->getCode();
            $message = $exception->getMessage();
            $code = $code == 0 ? 404 : $code;
            //公共的异常页面
            if (view()->exists('errors.' . $code)) {
                return response()->view('errors.' . $code, ['message' => $message], $code);
            }
            //公共的404页面
            return response()->view('errors.404', ['message' => $message], 404);
        }elseif ($exception instanceof ValidationException){
            //参数效验错误
            $message = array_values($exception->errors())[0][0] ?: '';
            CommonReturn::fail(StatusCode::COMMON_PARAMS_VERIFY_ERROR,$message);
        }elseif ($exception instanceof AuthorizationException){
            //没有权限
            CommonReturn::fail(StatusCode::COMMON_NO_ACCESS);
        }elseif ($exception instanceof HttpException){
            if($exception->getStatusCode() == 405){
                //请求方式错误
                CommonReturn::fail(StatusCode::COMMON_REQUEST_METHOD_INVALID);
            }else{
                CommonReturn::response($exception->getMessage(),$exception->getStatusCode());
            }
        }elseif ($exception instanceof QueryException){
            $message = $exception->getMessage();
            //数据库存储失败

            CommonReturn::fail(StatusCode::COMMON_SAVE_FAILURE,$message);
        }elseif ($exception instanceof Throwable) {
            $data = [
                'file'=>$exception->getFile(),
                'line'=>$exception->getLine(),
                'code'=>$exception->getCode(),
                'message'=>$exception->getMessage(),
//                    'TraceAsString'=>$exception->getTraceAsString(),
            ];
            CommonReturn::fail(StatusCode::COMMON_UNKNOWN,$data['message'],$data);
        }
        return parent::render($request, $exception);
    }

}
